package com.lry.pda.bottom.c.backend.executor;

import com.lry.pda.bottom.c.backend.code.CodeKey;
import com.lry.pda.bottom.c.backend.code.CodeNode;
import com.lry.pda.bottom.c.frontend.Grammar;

public class StatementExecutor extends BaseExecutor{

    private enum LoopType {
        FOR,
        WHILE,
        DO_WHILE
    };

    @Override
    public void execute(CodeNode root) {
        int production = (int)root.getAttr(CodeKey.PRODUCTION);
        if(production== Grammar.FOR_OPTEXPR_TEST_ENDOPTEXPR_STAT_TO_STAT){
            //执行opt_expr初始化
            executeChild(root, 0);
            //执行Test
            while(isLoopContinue(root,LoopType.FOR)){
                //execute statment in for body
                executeChild(root, 3);

                //execute EndOptExpr
                executeChild(root, 2);
            }
        }else if(production==Grammar.WHILE_TEST_STAT_TO_STAT){
            while(isLoopContinue(root,LoopType.WHILE)){
                executeChild(root,1);
            }
        }else if(production==Grammar.DO_STAT_WHILE_TEST_TO_STAT){
            do{
                executeChild(root,0);
            }while (isLoopContinue(root,LoopType.DO_WHILE));
        }else if(production==Grammar.RETURN_SEMI_TO_STAT){
            continueExecute = false;
        }else if(production==Grammar.RETURN_EXPR_SEMI_TO_STAT){
            CodeNode child = executeChild(root,0);
            returnObj = child.getAttr(CodeKey.VALUE);
            continueExecute = false;
        }
        else{
            executeChildren(root);
        }
    }
    private boolean isLoopContinue(CodeNode root, LoopType type) {
        CodeNode res = null;
        if (type == LoopType.FOR || type==LoopType.DO_WHILE) {
            res = executeChild(root, 1);

        }else if(type == LoopType.WHILE){
            res = executeChild(root, 0);
        }
        int result = (Integer)res.getAttr(CodeKey.VALUE);
        return result != 0;
    }

}
